![Glue StudioでAurora Serverless v1からデータを取得して結合するGlue Jobを作ってみた](https://devio2023-media.developers.io/wp-content/uploads/2022/08/aws-glue.png)
Glue StudioでAurora Serverless v1からデータを取得して結合するGlue Jobを作ってみた
データアナリティクス事業本部の鈴木です。
Amazon AuroraのテーブルからAWS GlueのSparkジョブでデータを取得し結合する処理を作りたかったので、簡単な処理ですが試したのでご紹介します。
Auroraの検証環境を作ったことがなかったので、Aurora Serverless v1環境の準備からしてみました。
検証したいこと
Aurora Serverless v1のテーブルからGlue Jobでデータを取得して、S3バケットに保存するまでの環境構築とGlue Jobの作成がこの記事で検証したい内容です。
Auroraからは2テーブルからデータを取得し、結合してS3バケットに保存してみました。
Auroraは、Amazon Aurora Serverlessをv1からv2にアップグレードしてみた | DevelopersIOのどのAmazon Auroraを使う?に選び方の目安の記載があったので参考にしつつ、特にバージョン自体にはこだわりがなかったので、Aurora Serverless v1にしてみました。
環境構築
1. ネットワークの構築
以下のようなネットワーク構成を作成するはCloudFormationテンプレートを作成し、デプロイしました。
エンドポイントは以下の2つを作成します。
# | サービス | 種類 | 用途 |
---|---|---|---|
1 | com.amazonaws.ap-northeast-1.s3 |
ゲートウェイ型 | Glueジョブで処理した結果を保存する |
2 | com.amazonaws.ap-northeast-1.secretsmanager |
インターフェース型 | Auroraのデータベースアクセス時にクレデンシャルを取得する |
また、図中に表現していませんが、以下のセキュリティグループも作成します。
# | 論理ID | 説明 | 備考 |
---|---|---|---|
1 | GlueConnectionSecurityGroup | Glue接続用のセキュリティグループ | 今回はエンドポイントにもこのセキュリティグループを適用しました |
2 | AuroraSecurityGroup | Aurora用のセキュリティグループ |
テンプレートは以下です。
AWSTemplateFormatVersion: "2010-09-09" Parameters: EnvironmentName: Type: String VPCCIDR: Type: String Default: 10.192.0.0/16 PrivateSubnetCIDR1: Type: String Default: 10.192.0.0/24 PrivateSubnetCIDR2: Type: String Default: 10.192.1.0/24 Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VPCCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${EnvironmentName}-VPC # Private Subnetのネットワーク設定 PrivateSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref PrivateSubnetCIDR1 VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName}-PrivateSubnet1 PrivateRouteTable1: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName}-PrivateRouteTable1 PrivateSubnetRouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1 RouteTableId: !Ref PrivateRouteTable1 # Private Subnetのネットワーク設定 PrivateSubnet2: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref PrivateSubnetCIDR2 VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName}-PrivateSubnet2 PrivateRouteTable2: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName}-PrivateRouteTable2 PrivateSubnetRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet2 RouteTableId: !Ref PrivateRouteTable2 # セキュリティグループ GlueConnectionSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: GlueConnectionSecurityGroup VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName}-GlueConnectionSecurityGroup SelfRefGlueConnectionSecurityGroupIgress: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !GetAtt GlueConnectionSecurityGroup.GroupId IpProtocol: tcp FromPort: "0" ToPort: "65535" SourceSecurityGroupId: !GetAtt GlueConnectionSecurityGroup.GroupId AuroraSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: AuroraSecurityGroup VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${EnvironmentName}-AuroraSecurityGroup SecurityGroupIngress: - IpProtocol: tcp FromPort: 5432 ToPort: 5432 SourceSecurityGroupId: !Ref GlueConnectionSecurityGroup # エンドポイントの設定 EndpointS3: Type: AWS::EC2::VPCEndpoint Properties: RouteTableIds: - !Ref PrivateRouteTable1 - !Ref PrivateRouteTable2 ServiceName: !Sub com.amazonaws.${AWS::Region}.s3 VpcEndpointType: Gateway VpcId: !Ref VPC EndpointSecretManager: Type: AWS::EC2::VPCEndpoint Properties: VpcEndpointType: Interface ServiceName: !Sub com.amazonaws.${AWS::Region}.secretsmanager VpcId: !Ref VPC PrivateDnsEnabled: True SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 SecurityGroupIds: - !Ref GlueConnectionSecurityGroup
Glue接続用のセキュリティグループには、自己参照ルールを作成しています。これはAWS Glue 用 JDBC データストアに接続するための VPC の設定 - AWS Glueに記載があります。CloudFormationでの自己参照ルールはAWS CloudformationでSecurity Groupの自己参照の設定を行う - YOMON8.NETを参考にしました。
テンプレートのVPC部分は[小ネタ]Session ManagerでアクセスできるEC2を1発で作成するCloudFormationテンプレート作ってみた | DevelopersIOを参考にしました。
2. Aurora Serverless v1 クラスターの準備
Amazon RDSのコンソールでデータベース
からデータベースの作成
を押しました。
以下はデータベースの作成画面です。選択した箇所を説明します。
標準作成
でAurora (PostgreSQL Compatible)
を選び、利用可能なバージョンからAurora PostgreSQL (Compatible with PostgreSQL 11.16)
としました。テンプレートは開発/テスト
としました。
インスタンスの設定
でDBインスタンスクラスはサーバーレス
を選びました。検証のためなので、容量の範囲は最小AUCは2、最大AUCは4としました。
VPCおよびセキュリティグループは先に作成したものを選択しました。
クエリエディタを使いたかったので、Data APIは有効化しました。
ページ右下のデータベースの作成
を押して利用可能
となるのを待ちました。
3. データベースとテーブルの作成
Glueジョブからデータを取得できるよう、検証用のデータベースとユーザーおよびテーブルを作成しましたのでサンプルを紹介します。
アクション
のクエリ
からクエリエディタを起動しました。
データベースに接続します
ポップアップが出るので、マスターユーザーでpostgres
データベースに接続しました。このときに画面の表示に従ってシークレットマネジャーにシークレットを作成しました。
クエリエディタで以下のSQL文を順に実行し、glue_user
ユーザーとglue_sample_database
データベースを作成し、ユーザーにデータベースへのアクセス権を付与しました。
-- パスワードの文字列は自分のものに変更してください。 CREATE USER glue_user WITH PASSWORD 'パスワードの文字列'; CREATE DATABASE glue_sample_database; GRANT ALL PRIVILEGES ON DATABASE glue_sample_database TO glue_user;
ユーザーが作成できたら、glue_user
ユーザーでglue_sample_database
データベースに接続しました。このときに画面の表示に従ってシークレットマネジャーにシークレットを作成しました。
テーブルを作成し、サンプルデータを入れておきました。
CREATE TABLE name ( id INTEGER PRIMARY KEY, name VARCHAR(255) NOT NULL ); CREATE TABLE price ( id INTEGER PRIMARY KEY, price INTEGER NOT NULL ); INSERT INTO name (id, name) VALUES (1, 'Apple'), (2, 'Orange'), (3, 'Grape'), (4, 'Pineapple'), (5, 'Peach'); INSERT INTO price (id, price) VALUES (1, 150), (2, 120), (3, 390), (4, 400), (5, 350);
以下のようにデータが格納されました。
4. Glue接続の作成
まずGlue接続の作成からです。AWS GlueのコンソールでData Connections
よりCreate connection
を選びました。
以下のように設定を入力しました。ポイントは以下の3点です。
JDBC URL
は、AWS Glue 接続プロパティ - AWS GlueのPostgreSQLに沿うようにしました。Credential type
はSecret
として、先に作成したglue_user
ユーザーのシークレットを指定しました。Network options
は、先に作成したVPC・サブネット・セキュリティグループを指定しました。
5. Glue Job用サービスロールの作成
以下のテンプレートを使ってGlue Job用のサービスロールを作成しました。
※ もし使われる際は、ロール名はAWSGlueServiceRole-Studio-CM-nayuts
にハードコードしてあるので適当に変更してください。
Auroraから取得して加工したデータをPUTするS3バケットおよびシークレットへのアクセス権を定義しました。Auroraのデータベース自体へのアクセスは、既に作成したGlue接続およびGlue用ユーザーにて制御しています。
AWSTemplateFormatVersion: "2010-09-09" Description: Creating Glue Studio Execution Role for Aurora Data Parameters: MartBucketName: Description: Backet Name for Data Mart. Type: String SecretARNforAuroraUser: Description: Secret ARN for Aurora User . Type: String Resources: GlueStudioExecutionRole: Type: AWS::IAM::Role Properties: # Role名はAWSGlueServiceRole-Studio-から始まる名前に変更してください。 RoleName: AWSGlueServiceRole-Studio-CM-nayuts AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: glue.amazonaws.com Action: "sts:AssumeRole" Path: "/" Policies: - PolicyName: GlueStudioS3AccessPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: [ "s3:*" ] Resource: [ !Sub "arn:aws:s3:::${MartBucketName}", !Sub "arn:aws:s3:::${MartBucketName}/*" ] - PolicyName: GlueStudioSecretManagerAccessPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: [ "secretsmanager:GetSecretValue" ] Resource: [ !Sub "${SecretARNforAuroraUser}" ] ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
MartBucketName
に名前を入れるS3バケットは、今回はあらかじめ作ってあった検証用のS3バケットを使用しました。S3バケットに関しては作成自体は例えばマネジメントコンソールなどから簡単にできます。
Glueジョブの作成と実行
Glueジョブの作成
今回はGlue Studioでジョブを作成してみました。ノードをいくつか作っているので、ある程度の粒度に分けて記載します。
全体像
まず全体像ですが、以下のようなジョブを作成しました。
2テーブルのデータを取得して、片方のテーブルはJOINのため絡む名を変更しておきました。JOINした後、不要なカラムを落としてS3に保存しました。
テーブルからの読み出し
まずname
テーブルからの読み出し設定です。
Node properties
タブではノード名を入力し、Node type
をPostgres
としました。
Data source properties - PostgreSQL
タブにて、JDBC source
でJDBC connection details
を選び、Connection name
で先ほど作成したGlue接続を指定しました。Table name
にてテーブルも指定しました。
Output schema
タブではEdit
からSchemaを設定しました。
price
テーブルからの読み出し設定も同様に行いました。
JOIN
name
テーブルはJOINのためRename field
の変換でカラム名を変更しました。
Join
の変換で2テーブルを結合しました。
結合キーは片方しか要らなかったので、不要なテーブル分は落としておきました。
S3への保存
最後にS3への保存設定をしました。今回はCSV形式としました。
Glueジョブの実行
エディタ右上の Save
ボタンでジョブを保存し、同じ並びのRun
ボタンでジョブを実行しました。
以下のようにS3バケットの指定したパスにファイルが出力されました。
念の為Athenaからテーブルを作成して検索すると、期待通りデータが作成されていることが確認できました。
最後に
今回はAmazon AuroraのテーブルからAWS GlueのSparkジョブでデータを取得し結合する処理を作成してみました。
Sparkジョブを作るだけだと比較的手軽な検証なのですが、VPCから全部作るとなるといろいろ知識が必要なので大変ですね。この記事では簡単にではありますが、VPCの作成からAurora Serverless v1クラスターの作成、Glue接続の設定なども盛り込んでみました。
参考になりましたら幸いです。